
#include "Regulator.h"

UINT16 desiredOutputVoltage;
UINT16 desiredMaximumOutputCurrent;

void setOutputVoltage(UINT16 _DC);
void setMaximumOutputCurrent(UINT16 _DC);
void adjustFineOutputVoltage (UINT8 _increment);
void adjustFineSetOutputCurrent (UINT8 _increment);
void activateOverCurrentProtection(void);
UINT16 readSetMaximumOutputCurrent(void);


void initializeRegulator(void) {
    //TRISC =  0xB8; // 10111000

    desiredOutputVoltage = 0;
    desiredMaximumOutputCurrent = 450;

    TRISCbits.TRISC1 = 0;
    TRISCbits.TRISC2 = 0;
    PR2 = 0xFF;
    CCPR1L = 0x00;
    CCPR2L = 0x00;
    T2CONbits.T2CKPS = 0;
    T2CONbits.TMR2ON = 1;
    CCP1CONbits.CCP1M3 = 1;
    CCP1CONbits.CCP1M2 = 1;
    CCP1CONbits.CCP1M1 = 0;
    CCP1CONbits.CCP1M0 = 0;

    CCP2CONbits.CCP2M3 = 1;
    CCP2CONbits.CCP2M2 = 1;
    CCP2CONbits.CCP2M1 = 0;
    CCP2CONbits.CCP2M0 = 0;
    TCLKCONbits.T3CCP1 = 0; // ECCP1 uses Timer1/2 and ECCP2 uses Timer3/4
    TCLKCONbits.T3CCP2 = 0;
    RPOR13 = 14;
    RPOR12 = 18;

//    iPPSOutput (OUT_PIN_PPS_RP12,OUT_FN_PPS_C1OUT);
//    OpenPWM1(0xFF);
//
//    SetOutputPWM1(SINGLE_OUT,PWM_MODE_1);
//    T2CONbits.TMR2ON = 1;
//    SetDCPWM1(500);

//
//    // Set our reload value
//    PR2 = 0xFF;
//
//    // Set to %50 power for testing
//    CCPR1L = 0x80;
//    CCPR2L = 0x80;
//
//
//    // The prescaler will be at 1
//    T2CONbits.T2CKPS = 0b00;
//
//    // Do not generate an interrupt
//
//    PIE1bits.TMR2IE = 0;
//
//    TCLKCONbits.T3CCP1 = 0; // ECCP1 uses Timer1/2 and ECCP2 uses Timer3/4
//    TCLKCONbits.T3CCP2 = 0; // ECCP1 uses Timer1/2 and ECCP2 uses Timer3/4
//
//    CCP1CONbits.CCP1M = 0b1100; // Set EECP1 as PWM mode
//    CCP1CONbits.P1M = 0b00; // Enhanged PWM mode: single ouptut
//    CCP2CONbits.CCP2M = 0b1100; // Set EECP1 as PWM mode
//    CCP2CONbits.P2M = 0b00; // Enhanged PWM mode: single ouptut
//
//    // Set up output routing to go to RB3 (RP6)
//    //RPOR12 = 18; // 14 is CCP1/P1A - ECCP1 PWM Output Channel A
//    //RPOR13 = 14;
//
//    TRISCbits.TRISC1 = 0;
//    TRISCbits.TRISC2 = 0;
//    PORTCbits.RC1 = 0;
//    PORTCbits.RC2 = 0;
//    T2CONbits.TMR2ON = 1;
//
//
//    PIR1bits.ADIF = 0;
//    SetDCPWM1(000);
//    SetDCPWM2(500);
    //ADC
    //
    //    ADCON0 = 0b00000001; //00000001
    //    ADCON1 = 0b10100011; //10100011
    //
    //    //ANCON1 = 0xF0;  //11110000

    ADCON0 = 0b00000001; //00000001
    
    ADCON1bits.ADFM = 1; // Resulst format 1= Right justified
    ADCON1bits.ADCAL = 0; // Normal A/D conversion operation
    ADCON1bits.ACQT = 1; // Acquition time 7 = 20TAD 2 = 4TAD 1=2TAD
    ADCON1bits.ADCS = 2; // Clock conversion bits 6= FOSC/64 2=FOSC/32
    ANCON1bits.VBGEN = 1; // Turn on the Bandgap needed for Rev A0 parts
    // ADCON0
    ADCON0bits.VCFG0 = 0; // Vref+ = AVdd
    ADCON0bits.VCFG1 = 0; // Vref- = AVss
    ADCON0bits.CHS = 2; // Select ADC channel
    ADCON0bits.ADON = 1; // Turn on ADC
    //OpenADC(ADC_FOSC_16 & ADC_RIGHT_JUST & ADC_8_TAD, ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, 0x00);

  
    ANCON0bits.PCFG0 = 0;
    ANCON0bits.PCFG1 = 0;
    ANCON0bits.PCFG2 = 0;
    ANCON0bits.PCFG3 = 0;

    TRISAbits.TRISA0 = 1;
    TRISAbits.TRISA1 = 1;
    TRISAbits.TRISA2 = 1;
    TRISAbits.TRISA3 = 1;
    //TODO: Add LOCK for PPS
   


}

void checkOutputStatus(void){
    UINT16 voltageDifference;
    UINT16 setMaximumCurrentDifference;
    UINT16 lastOutputVoltageReading;
    UINT16 lastSetMaximumCurrentOutput;

    //setOutputVoltage (desiredOutputVoltage);
    //setMaximumOutputCurrent (desiredMaximumOutputCurrent);
    
    //lastOutputVoltageReading = readOutputVoltage();
/*
    voltageDifference = lastOutputVoltageReading - desiredOutputVoltage;
    if(voltageDifference > VOLTAGE_HYSTERESIS || voltageDifference < -VOLTAGE_HYSTERESIS)
        adjustFineOutputVoltage(voltageDifference);
*/
    //lastSetMaximumCurrentOutput = readSetMaximumOutputCurrent();

    /*setMaximumCurrentDifference = lastSetMaximumCurrentOutput - desiredMaximumOutputCurrent;
    if(setMaximumCurrentDifference > SET_MAXIMUM_CURRENT_HYSTERESIS || voltageDifference < -SET_MAXIMUM_CURRENT_HYSTERESIS)
        adjustFineSetOutputCurrent(setMaximumCurrentDifference);*/
}

void setDesiredOutputVoltageAndCurrent(UINT16 _desiredOutputVoltage, UINT16 _desiredMaximumOutputCurrent){
    //desiredOutputVoltage = _desiredOutputVoltage;
    //desiredMaximumOutputCurrent = _desiredMaximumOutputCurrent;
    setOutputVoltage (_desiredOutputVoltage);
    setMaximumOutputCurrent (_desiredMaximumOutputCurrent);
}

void checkOutputCurrent (void){
    UINT16 lastOutputCurrentReading;
    lastOutputCurrentReading = readOutputCurrent();
    if (lastOutputCurrentReading > desiredMaximumOutputCurrent + MAXIMUM_CURRENT_HYSTERESIS)
        activateOverCurrentProtection();
}

void activateOverCurrentProtection(void){
    
}

void setOutputVoltage(UINT16 _outputVoltage) {

    //CCPR1L = _voltage/VOLTAGE_DIVIDER_RATIO/VOLTAGE_DIVIDER_RATIO*1024;
    //CCPR1L = _outputVoltage;
   
    SetDCPWM1(_outputVoltage);
    
}

void setMaximumOutputCurrent(UINT16 _maximumOutputCurrent) {

    //CCPR2L = _current/MAX_OUPUT_CURRENT*MAX_OUTPUT_CURRENT_PWM;
    //CCPR2L = _current;
    //CCPR2L = _maximumOutputCurrent;
    SetDCPWM2(_maximumOutputCurrent);
}

void adjustFineOutputVoltage (UINT8 _increment){

    CCPR1L+=_increment;

}

void adjustFineSetOutputCurrent (UINT8 _increment){

    CCPR2L+=_increment;

}

UINT16 readOutputVoltage(void) {
    UINT16 voltage;
    SetChanADC(ADC_CH2);
    ConvertADC();
    
    return (ReadADC());
}

UINT16 readOutputCurrent(void) {
    SetChanADC(ADC_CH0);
    ConvertADC();
    while (BusyADC());
    return ReadADC();
}

UINT16 readSetOutputVoltage(void){
    UINT16 current;
    SetChanADC(ADC_CH1);
    ConvertADC();
    while (BusyADC());

    return (ReadADC());
}

UINT16 readSetMaximumOutputCurrent(void){
    UINT16 current;
    SetChanADC(ADC_CH3);
    ConvertADC();
    while (BusyADC());

    return (ReadADC());
}


